package com.horizon.im.imServer.serverHandler;

import com.horizon.concurrent.FutureTaskScheduler;
import com.horizon.im.common.bean.msg.ProtoMsg;
import com.horizon.im.imServer.server.session.LocalSession;
import com.horizon.im.imServer.server.session.ServerSession;
import com.horizon.im.imServer.server.session.service.SessionManager;
import com.horizon.im.imServer.serverProcessor.ChatRedirectProcessor;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Data
@Slf4j
@Service("ChatRedirectHandler")
@ChannelHandler.Sharable
public class ChatRedirectHandler extends ChannelInboundHandlerAdapter {

    @Autowired
    ChatRedirectProcessor redirectProcessor;

    @Autowired
    SessionManager sessionManger;
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        LocalSession session = ctx.channel().attr(LocalSession.SESSION_KEY).get();

        if (null != session && session.isValid())
        {
            session.close();
            sessionManger.removeSession(session.getSessionId());
        }
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //判断消息实例
        if (null == msg || !(msg instanceof ProtoMsg.Message))
        {
            super.channelRead(ctx, msg);
            return;
        }

        //判断消息类型
        ProtoMsg.Message pkg = (ProtoMsg.Message) msg;
        ProtoMsg.HeadType headType = ((ProtoMsg.Message) msg).getType();
        if (!headType.equals(redirectProcessor.op()))
        {
            super.channelRead(ctx, msg);
            return;
        }

        //异步处理转发逻辑
        FutureTaskScheduler.add(()->
        {
            //判断是否登录，如果登录了，则为用户消息(即表示是由登录在该节点上的用户发上来的消息）
            LocalSession session = LocalSession.getSession(ctx);
            if (null != session && session.isLogin()){
                redirectProcessor.action(session,pkg);
            }

            //没有登录，则为中转消息
            ProtoMsg.MessageRequest request = pkg.getMessageRequest();
            List<ServerSession> toSession = SessionManager.getSingleInstance().getSessionsBy(request.getTo());

            for (ServerSession serverSession : toSession) {
                if (serverSession instanceof LocalSession) {
                    //将im消息发给接收方
                    serverSession.writeAndFlush(pkg);
                }

            }

        });
    }
}
